package com.yc.star.web;

import com.google.gson.Gson;
import com.yc.star.entity.User;
import com.yc.star.mapper.UserMapper;
import com.yc.star.vo.RedisUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.websocket.OnClose;
import javax.websocket.OnMessage;
import javax.websocket.OnOpen;
import javax.websocket.Session;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Hashtable;

@ServerEndpoint("/talk/{id}")
@Component
public class TalkServer {

    // 存放所有在线用户的集合
    static Hashtable<User,Session> sessions = new Hashtable<>();


    static UserMapper userMapper;
    @Resource
    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    @OnOpen//连接建立成功的方法
    public void onOpen(@PathParam("id") String id, Session session){
//         给当前用户发送已上线的用户信息
//        sessions.values().forEach(s->{
//            send(session, new Msg(
//                    ""+s.getUserProperties().get("id"),
//                    null,id,"上线了"));
//        });
        // 查询用户信息   错误的用法
        User user = userMapper.selectById(id);
        System.out.println(user.getUsername()+"连接成功");
        sessions.put(user, session);
        // 将 id 保存到会话
        session.getUserProperties().put("id",user);
//        sessions.values().forEach(s->{
//            send(s, new Msg(user,null,user,"上线了"));
//        });
    }

    @OnClose
    public void onClose(Session session){
        User user = (User) session.getUserProperties().get("id");
        sessions.remove(user);
        System.out.println(user.getUsername()+"断开连接");
//        sessions.values().forEach(s->{
//            send(s, new Msg(null,user,user,"下线了"));
//        });
    }

    // 接受到用户发送的消息 => 转发
    //收到客户端发送的消息调用的方法
    @OnMessage
    public void onMessage(String message, Session session){
        // 全部用户的群发
//        sessions.values().forEach(s->{
//            send(s, new Msg(null, null,null,
//                    (User) session.getUserProperties().get("id"),
//                    message));
//        });

        User senderUser = (User) session.getUserProperties().get("id");
        // 私聊  TODO
        Msg msg = Msg.fromJson(message);

        send(session, new Msg(null, null, null, senderUser, null, msg.sendMsg));
        try {
            if ("private".equals(msg.getType())) {
                sendPrivateMessage(msg.sendMsg, msg.acceptUser.getId(),session);
            } else {
                // 处理其他类型的消息
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        // 发送消息到发送者自己
//        sendPrivateMessage(message,null,session);
        // 自定义群发  TODO
    }

    Gson gson = new Gson();
    // 给指定的客户端发送消息
    public void send(Session session, Object obj){
        String json = gson.toJson(obj);
        try {
            session.getBasicRemote().sendText(json);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //私聊 targetUserId接收者id
    public void sendPrivateMessage(String message, Long targetUserId, Session senderSession) {
        User senderUser = (User) senderSession.getUserProperties().get("id");

        // 根据目标用户 ID 找到会话
        for (User user : sessions.keySet()) {
            if (user.getId().equals(targetUserId)) {
                Session targetSession = sessions.get(user);
                send(targetSession, new Msg(null, null,null, senderUser,null, message));
                return;
            }
        }
        // 发送消息到发送者自己
//        send(senderSession, new Msg(null, null, null, null, null, message));
        // 处理目标用户不在线的情况
//        send(senderSession, new Msg(null, null, null,null,null, "用户不在线"));
    }
}

@Data
@NoArgsConstructor
@AllArgsConstructor
class Msg{
    User onlineUser; // 上线用户
    User downlineUser; // 下线用户
    String type;        //私聊or群聊
    User sendUser;     // 发送消息的用户
    User acceptUser; //接收消息的用户
    String sendMsg;     // 发送的消息

    public static Msg fromJson(String json) {
        return new Gson().fromJson(json, Msg.class);
    }

    public String toJson() {
        return new Gson().toJson(this);
    }
}
